package cn.mg.mybatis.manager;

import org.apache.commons.lang3.ArrayUtils;

import javax.annotation.Resource;
import javax.naming.NamingException;
import javax.sql.DataSource;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.*;


/**
 * @author hezhaoming
 * @date 2019-10-31
 */
public class FreeDBManager {

    @Resource
    DataSource dataSource;

    private boolean usingCommon = false;

    public FreeDBManager() {
        this(true);
    }

    public FreeDBManager(boolean usingCommon) {
        this.usingCommon = usingCommon;
    }

    public Connection getConnection() throws NamingException, SQLException {
        DataSource ds = getDataSource();
        if (ds != null) {
            Connection conn = ds.getConnection();
            if (conn != null && !conn.getAutoCommit()) {
                conn.setAutoCommit(true);
            }
            return conn;
        }
        return null;
    }

    public void releaseConnection(Connection conn) {
        if (conn == null) {
            return;
        }
        try {
            if (conn.getAutoCommit()) {
                conn.setAutoCommit(false);
            }
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public DataSource getDataSource() throws NamingException {
        if (dataSource == null) {
            throw new NamingException();
        }
        return dataSource;
    }

    public long simpleCount(String table) throws NamingException, SQLException {
        Map<String, Object> info = simpleQueryOne("select count(1) as count from "
                + table);
        return (Long) info.get("count");
    }

    public Map<String, Object> simpleQueryOne(String sql)
            throws NamingException, SQLException {
        Connection conn = getConnection();
        PreparedStatement ps = null;
        if (this.usingCommon) {
            int wherePos = sql.toUpperCase().indexOf("WHERE");
            int isDeletePos = sql.toUpperCase().indexOf("IS_DELETE", wherePos);

            if (isDeletePos < 0) {
                if (wherePos < 0) {
                    sql += " where is_delete = 0";
                } else {
                    sql += " and is_delete = 0";
                }
            }
        }
        if (sql.toUpperCase().indexOf("LIMIT") < 0) {
            sql += " limit 0,1";
        }

        ResultSet rs = null;
        try {
            ps = conn.prepareStatement(sql);
            rs = ps.executeQuery();
            ResultSetMetaData rsmd = null;
            while (rs.next()) {
                Map<String, Object> row = new LinkedHashMap<>();
                if (rsmd == null) {
                    rsmd = rs.getMetaData();
                }
                for (int i = 1; i <= rsmd.getColumnCount(); i++) {
                    row.put(rsmd.getColumnLabel(i), rs.getObject(i));
                }

                return row;
            }
        } finally {
            if (rs != null) {
                rs.close();
            }

            if (ps != null) {
                ps.close();
            }

            releaseConnection(conn);
        }
        return null;
    }

    public List<Map<String, Object>> simpleQuery(String sql)
            throws NamingException, SQLException {
        Connection conn = null;
        try {
            conn = getConnection();
            return simpleQuery(sql, conn);
        } finally {
            releaseConnection(conn);
        }
    }

    public List<Map<String, Object>> simpleQuery(String sql, Connection conn)
            throws SQLException {
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = conn.prepareStatement(sql);
            rs = ps.executeQuery();
            List<Map<String, Object>> r = new ArrayList<>();
            ResultSetMetaData rsmd = null;
            while (rs.next()) {
                Map<String, Object> row = new LinkedHashMap<String, Object>();
                if (rsmd == null) {
                    rsmd = rs.getMetaData();
                }
                for (int i = 1; i <= rsmd.getColumnCount(); i++) {
                    row.put(rsmd.getColumnLabel(i), rs.getObject(i));
                }
                r.add(row);
            }
            return r;
        } finally {
            if (rs != null) {
                rs.close();
            }

            if (ps != null) {
                ps.close();
            }

        }
    }

    public int simpleUpdate(String sql) throws NamingException, SQLException {
        Connection conn = null;
        try {
            conn = getConnection();
            return simpleUpdate(sql, conn);
        } finally {
            releaseConnection(conn);
        }
    }

    public int simpleUpdate(String sql, Connection conn)
            throws NamingException, SQLException {
        if (conn == null) {
            throw new NamingException("conn is null");
        }
        PreparedStatement ps = null;
        try {
            ps = conn.prepareStatement(sql);
            return ps.executeUpdate();
        } finally {
            if (ps != null) {
                ps.close();
            }

        }
    }

    public boolean simpleExecute(String sql) throws NamingException,
            SQLException {
        Connection conn = null;
        try {
            conn = getConnection();
            return simpleExecute(sql, conn);
        } finally {
            releaseConnection(conn);
        }
    }

    public boolean simpleExecute(String sql, Connection conn)
            throws NamingException, SQLException {
        if (conn == null) {
            throw new NamingException("conn is null");
        }
        PreparedStatement ps = null;
        try {
            ps = conn.prepareStatement(sql);
            return ps.executeUpdate() >= 1;
        } finally {
            if (ps != null) {
                ps.close();
            }

        }
    }

    public String currentTime() {
        StringBuffer sql = new StringBuffer();
        sql.append("select now() as now ");
        Map<String, Object> dat;
        try {
            dat = simpleQueryOne(sql.toString());
            String now = dat.get("now").toString();
            return now;
        } catch (NamingException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        SimpleDateFormat format = new SimpleDateFormat(
                "yyyy-MM-dd HH:mm:ss.SSS");

        Date d = new Date(System.currentTimeMillis());
        return format.format(d);
    }

    public long currentTimeMillis() {
        StringBuffer sql = new StringBuffer();
        sql.append("select now() as now ");
        Map<String, Object> dat;
        try {
            dat = simpleQueryOne(sql.toString());
            Timestamp now = (Timestamp) dat.get("now");
            return now.getTime();
        } catch (NamingException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return System.currentTimeMillis();
    }

    public boolean add(Map<String, Object> args, String table, String fields[])
            throws NamingException, SQLException {
        Connection conn = null;
        try {
            conn = getConnection();
            return add(args, table, fields, conn);
        } finally {
            releaseConnection(conn);
        }
    }

    public long count(Map<String, Object> args, String table, String[] fields)
            throws NamingException, SQLException {
        Connection conn = null;
        try {
            conn = getConnection();
            return count(args, table, fields, conn);
        } finally {
            releaseConnection(conn);
        }
    }

    public long count(Map<String, Object> args, String table, String[] fields,
                      Connection conn) throws SQLException {
        if (fields == null) {
            return 0;
        }
        StringBuffer sql = new StringBuffer();
        StringBuffer sel = new StringBuffer();
        sql.append("select count(1) as count ");
        sql.append(sel);
        sql.append(" from ");
        sql.append(table);
        StringBuffer where = new StringBuffer();

        for (String key : args.keySet()) {
            if (where.length() > 0) {
                where.append(" and ");
            }
            if (key.equals("gmt_modified")) {
                where.append(" gmt_modified ");
                where.append(" > ? ");
            } else {
                if (ArrayUtils.contains(fields, key)) {
                    where.append(" `");
                    where.append(key);
                    where.append("` ");
                    where.append(" = ? ");
                }
            }

        }

        if (this.usingCommon) {
            if (where.length() > 0) {
                sql.append(" where ");
                sql.append(where);
                sql.append(" and is_delete = 0");
            } else {
                sql.append(" where is_delete = 0");
            }
        } else {
            if (where.length() > 0) {
                sql.append(" where ");
                sql.append(where);
            }
        }
        PreparedStatement ps = conn.prepareStatement(sql.toString());

        int index = 1;
        for (String key : args.keySet()) {
            if (ArrayUtils.contains(fields, key)) {
                ps.setObject(index, args.get(key));
                index++;
            }
        }

        ResultSet rs = ps.executeQuery();

        if (rs.next()) {
            return rs.getLong("count");
        }

        return 0;
    }

    public List<Map<String, Object>> query(Map<String, Object> query,
                                           String table, String fields[]) throws NamingException, SQLException {
        Connection conn = null;
        try {
            conn = getConnection();
            return query(query, table, fields, conn);
        } finally {
            releaseConnection(conn);
        }
    }

    public List<Map<String, Object>> query(Map<String, Object> query,
                                           String table, String fields[], Connection conn)
            throws SQLException {
        if (fields == null) {
            return new ArrayList<Map<String, Object>>();
        }

        StringBuffer sql = new StringBuffer();
        StringBuffer sel = new StringBuffer();
        sql.append("select ");

        if (query.containsKey("select") && query.get("select") instanceof List) {
            List<String> selectFields = (List<String>) query.get("select");
            for (String f : selectFields) {
                if (!ArrayUtils.contains(fields, f)) {
                    continue;
                }
                if (sel.length() > 0) {
                    sel.append(",");
                }
                sel.append("`");
                sel.append(f);
                sel.append("`");
            }
        } else {
            for (String f : fields) {
                if (sel.length() > 0) {
                    sel.append(",");
                }
                sel.append("`");
                sel.append(f);
                sel.append("`");
            }
        }
        sql.append(" ");
        sql.append(sel);
        sql.append(" from ");
        sql.append(table);
        sql.append(" ");
        if (query.containsKey("where") && query.get("where") instanceof List) {
            List<Map<String, Object>> where = (List<Map<String, Object>>) query
                    .get("where");
            if (where.size() > 0) {
                sql.append("where ");
            }
            int i = 0;
            for (Map<String, Object> cond : where) {
                String field = (String) cond.get("field");
                String op = (String) cond.get("op");
                if (ArrayUtils.contains(fields, field)) {
                    if (i > 0) {
                        sql.append(" and ");
                    }
                    sql.append("`");
                    sql.append(field);
                    sql.append("`");
                    sql.append(" ");
                    sql.append(op);
                    sql.append(" ");
                    sql.append("?");
                    i++;
                }

            }
        }

        PreparedStatement ps = conn.prepareStatement(sql.toString());

        int index = 1;
        if (query.containsKey("where") && query.get("where") instanceof List) {
            List<Map<String, Object>> where = (List<Map<String, Object>>) query
                    .get("where");
            for (Map<String, Object> cond : where) {
                String field = (String) cond.get("field");
                if (ArrayUtils.contains(fields, field)) {
                    ps.setObject(index, cond.get("value"));
                    index++;
                }

            }
        }

        ResultSet rs = ps.executeQuery();

        List<Map<String, Object>> r = new ArrayList<Map<String, Object>>();
        ResultSetMetaData rsmd = null;
        while (rs.next()) {
            Map<String, Object> row = new LinkedHashMap<String, Object>();
            if (rsmd == null) {
                rsmd = rs.getMetaData();
            }
            for (int i = 1; i <= rsmd.getColumnCount(); i++) {
                row.put(rsmd.getColumnLabel(i), rs.getObject(i));
            }
            r.add(row);
        }

        return r;
    }

    public List<Map<String, Object>> list(Map<String, Object> args,
                                          String table, String fields[], int offset, int count)
            throws NamingException, SQLException {
        Connection conn = null;
        try {
            conn = getConnection();
            return list(args, table, fields, conn, offset, count);
        } finally {
            releaseConnection(conn);
        }
    }

    public List<Map<String, Object>> list(Map<String, Object> args,
                                          String table, String fields[], Connection conn, int offset,
                                          int count) throws SQLException {
        if (fields == null) {
            return new ArrayList<Map<String, Object>>();
        }

        StringBuffer sql = new StringBuffer();
        StringBuffer sel = new StringBuffer();
        sql.append("select ");

        for (String f : fields) {
            if (sel.length() > 0) {
                sel.append(",");
            }
            sel.append("`");
            sel.append(f);
            sel.append("`");
        }
        sql.append(" ");
        sql.append(sel);
        sql.append(" from ");
        sql.append(table);
        // sql.append(" where last_update >= ? ");// order by last_update asc
        // limit
        // 0,1000
        StringBuffer where = new StringBuffer();

        for (String key : args.keySet()) {
            if (ArrayUtils.contains(fields, key) && where.length() > 0) {
                where.append(" and ");
            }
            if (ArrayUtils.contains(fields, key)) {
                where.append(" `");
                where.append(key);
                where.append("` ");
                where.append(" = ? ");
            }

        }

        if (this.usingCommon) {
            if (where.length() > 0) {
                sql.append(" where ");
                sql.append(where);
                sql.append(" and is_delete = 0");
            } else {
                sql.append(" where is_delete = 0");
            }
            sql.append(" ");
            sql.append(" order by gmt_modified asc limit " + offset + "," + count
                    + "");
        } else {
            sql.append(" ");
            sql.append(" limit " + offset + "," + count
                    + "");
        }

        PreparedStatement ps = conn.prepareStatement(sql.toString());

        int index = 1;
        for (String key : args.keySet()) {
            if (ArrayUtils.contains(fields, key)) {
                ps.setObject(index, args.get(key));
                index++;
            }
        }
        ResultSet rs = ps.executeQuery();

        List<Map<String, Object>> r = new ArrayList<Map<String, Object>>();
        ResultSetMetaData rsmd = null;
        while (rs.next()) {
            Map<String, Object> row = new LinkedHashMap<String, Object>();
            if (rsmd == null) {
                rsmd = rs.getMetaData();
            }
            for (int i = 1; i <= rsmd.getColumnCount(); i++) {
                row.put(rsmd.getColumnLabel(i), rs.getObject(i));
            }
            r.add(row);
        }

        return r;
    }

    public List<Map<String, Object>> list(Map<String, Object> args,
                                          String table, String fields[]) throws NamingException, SQLException {
        Connection conn = null;
        try {
            conn = getConnection();
            return list(args, table, fields, conn);
        } finally {
            releaseConnection(conn);
        }
    }

    public List<Map<String, Object>> list(Map<String, Object> args,
                                          String table, String fields[], Connection conn)
            throws SQLException {
        if (fields == null) {
            return new ArrayList<Map<String, Object>>();
        }

        StringBuffer sql = new StringBuffer();
        StringBuffer sel = new StringBuffer();
        sql.append("select ");

        for (String f : fields) {
            if (sel.length() > 0) {
                sel.append(",");
            }
            sel.append("`");
            sel.append(f);
            sel.append("`");
        }
        sql.append(" ");
        sql.append(sel);
        sql.append(" from ");
        sql.append(table);
        // sql.append(" where last_update >= ? ");// order by last_update asc
        // limit
        // 0,1000
        StringBuffer where = new StringBuffer();

        for (String key : args.keySet()) {
            if (ArrayUtils.contains(fields, key) && where.length() > 0) {
                where.append(" and ");
            }
            if (key.equals("gmt_modified")) {
                where.append(" gmt_modified ");
                where.append(" > ? ");
            } else {
                if (ArrayUtils.contains(fields, key)) {
                    where.append(" `");
                    where.append(key);
                    where.append("` ");
                    where.append(" = ? ");
                }
            }

        }

        if (this.usingCommon) {
            if (where.length() > 0) {
                sql.append(" where ");
                sql.append(where);
                sql.append(" and is_delete = 0");
            } else {
                sql.append(" where is_delete = 0");
            }
            sql.append(" ");
            sql.append(" order by gmt_modified asc limit 0,1000");
        } else {
            if (where.length() > 0) {
                sql.append(" where ");
                sql.append(where);
            }
        }
        PreparedStatement ps = conn.prepareStatement(sql.toString());

        int index = 1;
        for (String key : args.keySet()) {
            if (ArrayUtils.contains(fields, key)) {
                ps.setObject(index, args.get(key));
                index++;
            }
        }
        ResultSet rs = ps.executeQuery();

        List<Map<String, Object>> r = new ArrayList<Map<String, Object>>();
        ResultSetMetaData rsmd = null;
        while (rs.next()) {
            Map<String, Object> row = new LinkedHashMap<String, Object>();
            if (rsmd == null) {
                rsmd = rs.getMetaData();
            }
            for (int i = 1; i <= rsmd.getColumnCount(); i++) {
                row.put(rsmd.getColumnLabel(i), rs.getObject(i));
            }
            r.add(row);
        }

        return r;
    }

    public boolean replace(Map<String, Object> args, String table,
                           String fields[]) throws NamingException, SQLException {
        Connection conn = null;
        try {
            conn = getConnection();
            return replace(args, table, fields, conn);
        } finally {
            releaseConnection(conn);
        }
    }

    public boolean replace(Map<String, Object> args, String table,
                           String fields[], Connection conn) throws
            SQLException {
        if (fields == null) {
            return false;
        }

        StringBuffer sql = new StringBuffer();
        sql.append("replace into ");
        sql.append(table);
        sql.append("(");
        StringBuffer sqlFields = new StringBuffer();
        StringBuffer sqlValues = new StringBuffer();
        boolean hasFields = false;
        for (String f : fields) {
            Object o = args.get(f);
            if (o != null) {
                hasFields = true;
                if (sqlFields.length() > 0) {
                    sqlFields.append(",");
                }
                sqlFields.append("`");
                sqlFields.append(f);
                sqlFields.append("`");

                if (sqlValues.length() > 0) {
                    sqlValues.append(",");
                }
                sqlValues.append("?");
                // if (o instanceof String || o instanceof Date) {
                // sqlValues.append("'");
                // sqlValues.append(o);
                // sqlValues.append("'");
                // } else {
                // sqlValues.append(o);
                // }

            }
        }
        if (!hasFields)
            return true;
        if (this.usingCommon) {
            sqlFields.append(",gmt_create,gmt_modified,is_delete");
        }
        sql.append(sqlFields);
        sql.append(") values(");
        if (this.usingCommon) {
            sqlValues.append(",now(),now(),0");
        }
        sql.append(sqlValues);
        sql.append(")");

        PreparedStatement ps = conn.prepareStatement(sql.toString());

        int index = 1;
        for (String f : fields) {
            Object o = args.get(f);
            if (o != null) {
                ps.setObject(index, o);
                index++;
            }
        }
        return ps.executeUpdate() >= 1;// simpleExecute(sql.toString(),
        // conn);
    }

    public boolean add(Map<String, Object> args, String table, String fields[],
                       Connection conn) throws SQLException {
        if (fields == null) {
            return false;
        }

        StringBuffer sql = new StringBuffer();
        sql.append("insert into ");
        sql.append(table);
        sql.append("(");
        StringBuffer sqlFields = new StringBuffer();
        StringBuffer sqlValues = new StringBuffer();
        boolean hasFields = false;
        for (String f : fields) {
            Object o = args.get(f);
            if (o != null) {
                hasFields = true;
                if (sqlFields.length() > 0) {
                    sqlFields.append(",");
                }
                sqlFields.append("`");
                sqlFields.append(f);
                sqlFields.append("`");

                if (sqlValues.length() > 0) {
                    sqlValues.append(",");
                }
                sqlValues.append("?");

                // if (o instanceof String || o instanceof Date) {
                // sqlValues.append("'");
                // sqlValues.append(o);
                // sqlValues.append("'");
                // } else {
                // sqlValues.append(o);
                // }

            }
        }
        if (!hasFields)
            return true;
        sql.append(sqlFields);
        if (this.usingCommon) {
            sql.append(",gmt_create,gmt_modified,is_delete");
        }
        sql.append(") values(");
        sql.append(sqlValues);
        if (this.usingCommon) {
            sql.append(",now(),now(),0");
        }
        sql.append(")");

        PreparedStatement ps = conn.prepareStatement(sql.toString());
        int index = 1;
        for (String f : fields) {
            Object o = args.get(f);
            if (o != null) {
                ps.setObject(index, o);
                index++;
            }
        }
        return ps.executeUpdate() >= 1;// simpleExecute(sql.toString(),
        // conn);
    }

    public boolean update(Map<String, Object> args, String table, String id,
                          String fields[]) throws NamingException, SQLException {
        Connection conn = null;
        try {
            conn = getConnection();
            return update(args, table, id, fields, conn);
        } finally {
            releaseConnection(conn);
        }
    }

    public boolean update(Map<String, Object> args, String table, String id,
                          String fields[], Connection conn) throws
            SQLException {
        if (fields == null) {
            return false;
        }

        StringBuffer sql = new StringBuffer();
        sql.append("update ");
        sql.append(table);
        sql.append(" set ");
        StringBuffer sqlFields = new StringBuffer();
        boolean hasFields = false;
        for (String f : fields) {
            Object o = args.get(f);
            if (o != null) {
                hasFields = true;
                if (sqlFields.length() > 0) {
                    sqlFields.append(",");
                }
                sqlFields.append("`");
                sqlFields.append(f);
                sqlFields.append("`");
                sqlFields.append("=");
                sqlFields.append("?");
                // if (o instanceof String || o instanceof Date) {
                // sqlFields.append("'");
                // sqlFields.append(o);
                // sqlFields.append("'");
                // } else {
                // sqlFields.append(o);
                // }

            }
        }
        if (!hasFields) {
            return true;
        }

        sql.append(sqlFields);
        if (this.usingCommon) {
            sql.append(",gmt_modified = now() ");
        }
        sql.append(" where ");
        sql.append(fields[0]);
        sql.append("='");
        sql.append(id);
        sql.append("'");
        if (this.usingCommon) {
            sql.append(" and is_delete = 0");
        }

        PreparedStatement ps = conn.prepareStatement(sql.toString());

        int index = 1;
        for (String f : fields) {
            Object o = args.get(f);
            if (o != null) {
                ps.setObject(index, o);
                index++;
            }
        }
        return ps.executeUpdate() >= 1;// simpleUpdate(sql.toString(),
        // conn) == 1 ? true :
        // false;
    }

    public boolean remove(String id, String table, String fields[])
            throws NamingException, SQLException {
        Connection conn = null;
        try {
            conn = getConnection();
            return remove(id, table, fields, conn);
        } finally {
            releaseConnection(conn);
        }
    }

    public boolean remove(String id, String table, String fields[],
                          Connection conn) throws NamingException, SQLException {
        if (fields == null) {
            return false;
        }
        StringBuffer sql = new StringBuffer();
        if (this.usingCommon) {
            sql.append("update ");
            sql.append(table);
            sql.append(" set ");
            sql.append("is_delete = 1");
            sql.append(",gmt_modified = now()");
            sql.append(" where ");
            sql.append(fields[0]);
            sql.append("='");
            sql.append(id);
            sql.append("'");
        } else {
            sql.append("delete from ");
            sql.append(table);
            sql.append(" where ");
            sql.append(fields[0]);
            sql.append("=");
            sql.append(id);

        }
        return simpleUpdate(sql.toString(), conn) >= 1;
    }

    public boolean remove(String table, String fields[],
                          Map<String, Object> values) throws NamingException, SQLException {
        Connection conn = null;
        try {
            conn = getConnection();
            return remove(table, fields, values, conn);
        } finally {
            releaseConnection(conn);
        }
    }

    public boolean remove(String table, String fields[],
                          Map<String, Object> values, Connection conn)
            throws SQLException {
        if (fields == null) {
            return false;
        }
        StringBuffer sqlFields = new StringBuffer();
        boolean hasFields = false;
        for (String f : fields) {
            Object o = values.get(f);
            if (o != null) {
                hasFields = true;
                if (sqlFields.length() > 0) {
                    sqlFields.append(" and ");
                }
                sqlFields.append("`");
                sqlFields.append(f);
                sqlFields.append("`");
                sqlFields.append("=");
                sqlFields.append("?");
                // if (o instanceof String || o instanceof Date) {
                // sqlFields.append("'");
                // sqlFields.append(o);
                // sqlFields.append("'");
                // } else {
                // sqlFields.append(o);
                // }

            }
        }
        if (!hasFields) {
            return true;
        }

        StringBuffer sql = new StringBuffer();
        if (this.usingCommon) {

            sql.append("update ");
            sql.append(table);
            sql.append(" set ");
            sql.append("is_delete = 1");
            sql.append(",gmt_modified = now()");
            sql.append(" where ");
            sql.append(sqlFields);
        } else {
            sql.append("delete from ");
            sql.append(table);
            sql.append(" where ");
            sql.append(sqlFields);
        }

        PreparedStatement ps = conn.prepareStatement(sql.toString());
        int index = 1;
        for (String f : fields) {
            Object o = values.get(f);
            if (o != null) {
                ps.setObject(index, o);
                index++;
            }
        }
        if (index == 1) {
            return false;
        }


        return ps.executeUpdate() >= 1;// simpleUpdate(sql.toString(),
        // conn) >= 1 ? true :
        // false;
    }

    public boolean removeForce(Map<String, Object> where, String table)
            throws NamingException, SQLException {
        Connection conn = null;
        try {
            conn = getConnection();
            return removeForce(where, table, conn);
        } finally {
            releaseConnection(conn);
        }
    }

    public boolean removeForce(Map<String, Object> where, String table,
                               Connection conn) throws NamingException, SQLException {
        StringBuffer sql = new StringBuffer();
        sql.append("delete from ");
        sql.append(table);
        sql.append(" where ");
        StringBuffer whereSql = new StringBuffer();
        for (String key : where.keySet()) {
            if (whereSql.length() > 0) {
                whereSql.append(" and ");
            }
            whereSql.append("`");
            whereSql.append(key);
            whereSql.append("`");
            Object val = where.get(key);
            if (val instanceof String || val instanceof Date) {
                whereSql.append("='");
                whereSql.append(val.toString());
                whereSql.append("'");
            } else {
                whereSql.append(val.toString());
            }
        }
        if (whereSql.length() == 0) {
            return false;
        }
        sql.append(whereSql);
        simpleUpdate(sql.toString(), conn);
        return true;
    }


}
